package com.example.cwgl.configs;


import com.example.cwgl.entity.UserInfo;
import com.example.cwgl.utils.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Map;

/**
* description: TODO 基于Spring MVC 的拦截器
* @author
* @date 实现 HandlerInterceptor 接口，覆盖 preHandle, postHandle, afterCompletion 方法。
*/
public class LoggerInterceptor implements HandlerInterceptor {

    private static Logger logger = LoggerFactory.getLogger(LoggerInterceptor.class);
    private static HttpSession session;
    private static String userid;
    private static StringBuilder sb = new StringBuilder();
    @Override
    /**
     * 作用：在请求处理前记录用户访问的 URL。*/
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 初始化 session 并获取用户信息
        if (session==null && (session = request.getSession()) != null){
            UserInfo userInfo = (UserInfo)session.getAttribute(Config.CURRENT_USERNAME);
            userid = userInfo == null? request.getHeader("userid") : userInfo.getId().toString();
        }
        sb.setLength(0);
        // 记录用户访问日志
        sb.append("用户编号【")
            .append(userid)
            .append("】正在访问：")
            .append(request.getRequestURL().toString());
        logger.info(sb.toString());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //忽略静态资源，忽略静态资源日志后，日志文件更聚焦于关键业务接口（如 /api/users），便于排查问题。
        //打印日子信息
        if (!request.getRequestURI().contains("/static/")){
            sb.setLength(0);
            sb.append("Method:").append(((HandlerMethod)handler).getShortLogMessage());
            logger.info(sb.toString());
            Map<String, String[]> parameters = request.getParameterMap();
            if (parameters.size() > 0){
                sb.setLength(0);
                sb.append("Parameters: {");
                for (String key : parameters.keySet()){
                    String value = parameters.get(key)[0];
                    if (value != null && !value.isEmpty()){
                        sb.append(key +":"+parameters.get(key)[0]+",");
                    }
                }
                if (sb.lastIndexOf(",")!=-1){
                    sb.deleteCharAt(sb.lastIndexOf(","));
                }
                sb.append("}");
                logger.info(sb.toString());
            }
        }

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//在请求完成后记录结束日志。
        sb.setLength(0);
        sb.append("用户编号【")
            .append(userid)
            .append("】")
            .append(request.getRequestURL().toString())
            .append(" 访问结束... ");

        logger.info(sb.toString());


    }
}
/**
 * Spring MVC 是 Spring 框架的一个模块，
 * 专门用于构建 基于 Java 的 Web 应用程序。
 * 它遵循经典的 MVC（Model-View-Controller）设计模式，
 * 将应用程序分为三层：模型（数据）、视图（界面）和控制器（逻辑），
 * 从而实现代码的解耦和高可维护性。*/


/**HandlerInterceptor 是 Spring MVC 框架中的核心拦截器接口，用于在请求处理的特定阶段插入自定义逻辑。其核心特性及作用如下：

 ‌一、定义与核心方法‌
 HandlerInterceptor 接口定义了三个关键方法：
 preHandle
 在控制器方法执行前调用，通常用于权限校验、日志记录等预处理。返回 true 继续流程，返回 false 中断请求。
 postHandle
 在控制器方法执行后、视图渲染前触发，可修改模型数据或视图响应。
 afterCompletion
 在整个请求完成后调用（包括视图渲染结束），适合资源清理或耗时统计。*/